package com.simba.server.controllers.impl;

import com.simba.common.jsonserver.JsonChannelManager;
import com.simba.server.commands.impl.record.RecordPacketOffReportCmd;
import com.simba.server.components.CommandExecutor;
import com.simba.server.components.SortCommonDefines;
import com.simba.server.components.SortProtocolCreator;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

import com.simba.common.log.LogUtil;
import com.simba.server.ServerManager;

import com.simba.server.commands.impl.record.RecordPacketOffCmd;
import com.simba.server.commands.impl.web.WebPacketOffCmd;
import com.simba.server.commands.impl.web.WebRecycleSlotStateCmd;
import com.simba.server.components.SlotManager;
import com.simba.server.components.data.SlotInfo;
import com.simba.server.components.data.SortInfo;
import com.simba.server.controllers.IPacketOffController;
import org.jboss.netty.channel.Channel;
import org.json.JSONObject;

import java.sql.Timestamp;

public class PacketOffController implements IPacketOffController
{
	private static final Logger logger = Logger.getLogger(PacketOffController.class);

	@Override
	public void onPacketOffMessage(SortInfo sortInfo)
	{
		try
		{
			this.offerSortResult(sortInfo);
			this.sendToDWSClient(sortInfo);
			this.restorePacketOff(sortInfo);
			this.recordSortResult(sortInfo);
			this.offerAddScanInfo(sortInfo);
		}
		catch (Exception ex)
		{
			LogUtil.LogError(PacketOffController.logger, "Handle NB PacketOff Message In BestPacketOff Handler Error -- Exception : " + ex);
		}
	}

	private void recordSortResult(SortInfo sortInfo)
	{
		try
		{
			StringBuilder info = new StringBuilder();

			info.append("[Key:SortResult],");
			info.append("[SorterID:").append(sortInfo.getSorterId()).append("],");
			info.append("[Barcode:").append(sortInfo.getBarcode()).append("],");
			info.append("[BarcodeList:").append(sortInfo.getBarcodeList()).append("],");
			info.append("[PlcID:").append(sortInfo.getPlcId()).append("],");
			info.append("[DroppedSlot:").append(sortInfo.getDroppedSlotId()).append("],");
			info.append("[ServerSlotId:").append(StringUtils.join(sortInfo.getSlotsList(), ",")).append("],");
			info.append("[DroppedErrorCode:").append(sortInfo.getErrorCodePLC()).append("],");
			info.append("[ServerErrorCode:").append(sortInfo.getErrorCodeSVR()).append("]");

			String content = info.toString();

			LogUtil.LogDebug(logger, content);
		}
		catch (Exception ex)
		{
			LogUtil.LogError(logger, "[PacketOffDecoder.recordSortResult] Error:" + ex.getMessage());
		}

	}

	private void offerAddScanInfo(SortInfo sortInfo)
	{
		try
		{
			ServerManager.getInstance().getScanMessageTask().offerScanMessageToQueue(sortInfo);
		}
		catch (Exception ex)
		{
			LogUtil.LogError(PacketOffController.logger, "Handle NB PacketOff Message In offerAddScanInfo Handler Error -- Exception : " + ex);
		}
	}

	private Boolean offerSortResult(SortInfo sortInfo)
	{
		Boolean ret = false;

		try
		{
			int droppedSlotId = sortInfo.getDroppedSlotId();
			String slotId = String.valueOf(droppedSlotId);

			Timestamp scannedTime = sortInfo.getTimestampPacketOn();
			if (scannedTime == null)
			{
				scannedTime = SortProtocolCreator.getInstance().createCurrentTimeStamp();
			}
			String scannedTimeContent = scannedTime.toString();
			sortInfo.setTimePacketOn(scannedTimeContent);

			Timestamp packetOffTime = sortInfo.getTimestampPacketOff();
			if (packetOffTime == null)
			{
				packetOffTime = SortProtocolCreator.getInstance().createCurrentTimeStamp();
			}
			String packetOffTimeContent = packetOffTime.toString();
			sortInfo.setTimePacketOff(packetOffTimeContent);

			SlotInfo slotInfo = SlotManager.getInstance().getSlotInfo(slotId);
			if (slotInfo == null)
			{
				sortInfo.setUploadFlag(SortCommonDefines.UPLOAD_DEFAULT_FLAG);
				return ret;
			}

			if (sortInfo.getUploadFlag() == SortCommonDefines.UPLOAD_NO_UPLOAD_FLAG)
			{
				return ret;
			}

			if (sortInfo.getUploadFlag() == SortCommonDefines.UPLOAD_ONLY_PACK_FLAG)
			{
				return ret;
			}

			int uploadNum = sortInfo.getUploadNum() + 1;

			String cmdName = null;
			if (sortInfo.getErrorCodePLC() == 0)
			{
				cmdName = WebPacketOffCmd.NAME;
			}
			else
			{
				cmdName = WebRecycleSlotStateCmd.NAME;
			}

			ret = CommandExecutor.executorWebCommand(cmdName, sortInfo, false);

			if (ret)
			{
				sortInfo.setUploadFlag(SortCommonDefines.UPLOAD_SUCCESS_FLAG);
			}
			else
			{
				sortInfo.setUploadFlag(SortCommonDefines.UPLOAD_ERROR_FLAG);
			}

			sortInfo.setUploadNum(uploadNum);
		}
		catch (Exception ex)
		{
			LogUtil.LogError(PacketOffController.logger, "Handle NB PacketOff Message In uploadSortInfo Handler Error -- Exception : " + ex);
			ret = false;
		}

		return ret;
	}

	private void restorePacketOff(SortInfo sortInfo)
	{
		try
		{
			boolean ret = CommandExecutor.executorSqlCommand(RecordPacketOffCmd.NAME, sortInfo, false);
			if (!ret)
			{
				ServerManager.getInstance().getDataRestoreTask().offerRestoreDataToQueue(sortInfo);
			}

			ret = CommandExecutor.executorSqlCommand(RecordPacketOffReportCmd.NAME, sortInfo, false);
			if (!ret)
			{
				LogUtil.LogError(logger, "Recode packet off report msg error, barcode:" + sortInfo.getBarcode());
			}
		}
		catch (Exception ex)
		{
			LogUtil.LogError(PacketOffController.logger, "Handle NB PacketOff Message In restorePacketOff Handler Error -- Exception : " + ex);
		}
	}

	private void sendToDWSClient(SortInfo wheelSortInfo)
	{
		JSONObject sendObj = new JSONObject();
		sendObj.put("ServiceName", "LinePacketOff");
		sendObj.put("SorterID", wheelSortInfo.getSorterId());
		sendObj.put("sortKey", wheelSortInfo.getBarcode());
		sendObj.put("dropChute", String.valueOf(wheelSortInfo.getDroppedSlotId()));
		sendObj.put("serverSlot", wheelSortInfo.getSlotsList().toString());
		sendObj.put("errorCode", String.valueOf(wheelSortInfo.getErrorCodeSVR()));
		sendObj.put("serverMsg", "success");

		LogUtil.LogInfo(logger,"发给监控"+sendObj.toString());
		Channel[] channels = JsonChannelManager.getInstance().getChannelList();

		for (Channel tmpChannel : channels) {
			if (tmpChannel == null) {
				continue;
			}
			JsonChannelManager.getInstance().commitResponse(tmpChannel, sendObj.toString().getBytes(), false);
		}
	}
}
